package com.feinno.urcs.group.http.handler;

import com.feinno.urcs.group.GroupConfiguration;
import com.feinno.urcs.group.GroupConstants;
import com.feinno.urcs.group.GroupError;
import com.feinno.urcs.group.GroupException;
import com.feinno.urcs.group.entity.GroupIndex;
import com.feinno.urcs.group.entity.GroupInfo;
import com.feinno.urcs.group.entity.GroupMember;
import com.feinno.urcs.group.entity.GroupMemberStatus;
import com.feinno.urcs.group.http.servlet.BaseHttpServlet;
import com.feinno.urcs.group.http.servlet.GroupHttpContext;
import com.feinno.urcs.group.http.util.HttpHelper;
import com.feinno.urcs.group.http.util.StringHelper;
import com.feinno.urcs.group.pd.upstream.entity.*;
import com.feinno.urcs.sip.UrcsSipFactory;
import com.feinno.urcs.types.MobileNo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sip.address.SipURI;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by wuzhiguo on 15-5-14.
 */
public class GetGroupInfoHandler extends BaseHttpServlet {

	private static final Logger LOGGER = LoggerFactory.getLogger(GetGroupInfoHandler.class);

	@Override
	public void process(final GroupHttpContext ctx) throws IOException {
		try {
			if (LOGGER.isInfoEnabled()) {
				String requestString = HttpHelper.getRequestString(ctx.getRequest(), ctx.getBodyString());
				LOGGER.info(String.format("Received Request: %s", requestString));
			}

			// 调用GroupService
			GroupIndex groupIndex = ctx.getGroupService().getGroupIndex(getGroupIdFromUri(ctx.getXuiIMPU().toString()));
			GroupInfo groupInfo = ctx.getGroupService().getGroupInfo(groupIndex);
			if (groupInfo == null) {
				String requestString = HttpHelper.getRequestString(ctx.getRequest(), ctx.getBodyString());
				LOGGER.error(String.format("getGroupInfo return null. Received Request: %s", requestString));
				ctx.getResponse().sendError(404, "GroupNotExist");
				return;
			}
			int groupInfoVer = ctx.getGroupInfoVersionCacheManager().getCurGrpInfoVer(groupIndex.getGroupId());
			if (groupInfoVer < 0) {
				groupInfoVer = 0;
			}
			byte[] responseBody = buildResponseBody(groupInfo);
			ctx.getResponse().setStatus(200);
			setDigestAuthenticationInfo(ctx);
			ctx.getResponse().setContentType("application/public-group+xml; charset=\"utf-8\"");
			ctx.getResponse().setContentLength(responseBody.length);
			ctx.getResponse().setHeader("ETag", String.valueOf(groupInfoVer));
			ctx.getResponse().getOutputStream().write(responseBody);
			ctx.getResponse().getOutputStream().flush();

			if (LOGGER.isInfoEnabled()) {
				String requestString = HttpHelper.getRequestString(ctx.getRequest(), ctx.getBodyString());
				String responseBodyString = new String(responseBody);
				LOGGER.info(String.format("process() Successfully.\n"
								+ "Received Request: %s\n"
								+ "Send Response Body: %s",
						requestString,
						responseBodyString));
			}

		} catch (GroupException gex) {
			GroupError error = gex.getError();
			String requestString = HttpHelper.getRequestString(ctx.getRequest(), ctx.getBodyString());
			LOGGER.error(String.format("process() GroupException. GroupError Code: %s Received Request: %s",
					error.getSipCode(), requestString), gex);
			ctx.getResponse().sendError(error.getSipCode(), "GroupError");
		} catch (Exception ex) {
			String requestString = HttpHelper.getRequestString(ctx.getRequest(), ctx.getBodyString());
			LOGGER.error(String.format("process() Error. Received Request: %s", requestString), ex);
			ctx.getResponse().sendError(500, "ServerError");
		}
	}

	private byte[] buildResponseBody(GroupInfo groupInfo) throws Exception {
		String groupUri = groupInfo.getGroupIndex().getConferenceUri();
		MobileNo groupAdmin = groupInfo.getGroupAdmin();

		PublicGroup publicGroup = new PublicGroup();
		PublicGroup_List list = new PublicGroup_List();
		PublicGroup_MetaData metaData = new PublicGroup_MetaData();
		publicGroup.setList(list);
		publicGroup.setMetaData(metaData);

		list.setName(groupInfo.getSubject());
		list.setUri(groupUri);
		list.setMax(String.valueOf(groupInfo.getLimitMemberCount()));

		List<PublicGroup_List_Entry> entryList = new ArrayList<>();
		list.setEntryList(entryList);

		if (groupInfo.getMembers() != null && groupInfo.getMembers().size() > 0) {
			for (int i = 0; i < groupInfo.getMembers().size(); i++) {
				GroupMember member = groupInfo.getMembers().get(i);
				PublicGroup_List_Entry entry = new PublicGroup_List_Entry();
				entryList.add(entry);

				SipURI memberSipURL = UrcsSipFactory.getAddressFactory().createSipURI(member.getMobileNo().toString(), GroupConfiguration.INSTANCE.getDomain());
				entry.setUri(memberSipURL.toString());

				// 只有PENDING状态是等待同意，其他都是正式群成员
				if (member.getIdentity() != 1 && member.getIdentity() != 3) {
					entryList.remove(entry);
					continue;
//					entry.setStatus("pending");
				} else {
					entry.setStatus("active");
				}

				if (member.getMobileNo().equals(groupAdmin)) {
					entry.setOwner("true");
				}

				entry.setDisplayName(new PublicGroup_List_Entry_DisplayName(member.getDisplayname()));
			}
		}

		SipURI creatorSipURL = UrcsSipFactory.getAddressFactory().createSipURI(groupAdmin.toString(), GroupConfiguration.INSTANCE.getDomain());
		metaData.setCreator(new PublicGroup_MetaData_Creator(creatorSipURL.toString()));
		metaData.setIdentifier(new PublicGroup_MetaData_Identifier(String.format(GroupConstants.PUBLIC_GROUP_IDENTIFIER_TEMPLATE, groupUri)));
		metaData.setTimestamp(new PublicGroup_MetaData_Timestamp(StringHelper.generateXmlDateFormatString(groupInfo.getCreateTime())));
		metaData.setNeedPermit(new PublicGroup_MetaData_NeedPermit("false"));

		return publicGroup.toXmlByteArray();
	}

}
